From 943f4e6d268ba2a8c0f7904701b6d5e678b57a5f Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Fri, 6 Oct 2006 16:27:06 +0100 Subject: [PATCH] [XEND] Proper support for devices with UUID. Removing old workaround with augmented VM UUIDs with devids. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendAPI.py | 36 ++++-- tools/python/xen/xend/XendConfig.py | 6 + tools/python/xen/xend/XendDomain.py | 46 +++---- tools/python/xen/xend/XendDomainInfo.py | 117 +++++++++++------- tools/python/xen/xend/server/DevController.py | 7 ++ 5 files changed, 130 insertions(+), 82 deletions(-) diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index 402e0bcbce..e91ee95e11 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -948,9 +948,14 @@ class XendAPI: # object methods def vbd_get_record(self, session, vbd_ref): xendom = XendDomain.instance() - return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref, - 'driver')) - + vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref) + if not vm: + return xen_api_error(XEND_ERROR_VIF_INVALID) + cfg = vm.get_dev_xenapi_config('vbd', vbd_ref) + if not cfg: + return xen_api_error(XEND_ERROR_UNKNOWN) + return xen_api_success(cfg) + # class methods def vbd_create(self, session, vbd_struct): xendom = XendDomain.instance() @@ -968,20 +973,20 @@ class XendAPI: # attributes (rw) def vbd_get_vm(self, session, vbd_ref): xendom = XendDomain.instance() - return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref, 'VM')) + return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM')) def vbd_get_vdi(self, session, vbd_ref): return xen_api_error(XEND_ERROR_UNSUPPORTED) def vbd_get_device(self, session, vbd_ref): xendom = XendDomain.instance() - return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref, + return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'device')) def vbd_get_mode(self, session, vbd_ref): xendom = XendDomain.instance() - return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref, + return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'mode')) def vbd_get_driver(self, session, vbd_ref): xendom = XendDomain.instance() - return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref, + return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'driver')) # Xen API: Class VIF @@ -1001,6 +1006,23 @@ class XendAPI: VIF_attr_inst = VIF_attr_rw + # object methods + def vif_get_record(self, session, vif_ref): + xendom = XendDomain.instance() + vm = xendom.get_vm_with_dev_uuid('vif', vif_ref) + if not vm: + return xen_api_error(XEND_ERROR_VIF_INVALID) + cfg = vm.get_dev_xenapi_config('vif', vif_ref) + if not cfg: + return xen_api_error(XEND_ERROR_UNKNOWN) + valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \ + self.Base_attr_ro + self.Base_attr_rw + for k in cfg.keys(): + if k not in valid_vif_keys: + del cfg[k] + + return xen_api_success(cfg) + # class methods def vif_create(self, session, vif_struct): xendom = XendDomain.instance() diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index ba6337b0c5..8fbf9cbb23 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -717,6 +717,12 @@ class XendConfig(dict): raise XendConfigError('Invalid restart event: %s = %s' % \ (event, str(self[event]))) + # Verify that {vif,vbd}_refs are here too + if 'vif_refs' not in self: + self['vif_refs'] = [] + if 'vbd_refs' not in self: + self['vbd_refs'] = [] + def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None): if dev_type not in XendDevices.valid_devices(): raise XendConfigError("XendConfig: %s not a valid device type" % diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 604c298db5..dee31a331b 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -563,22 +563,25 @@ class XendDomain: finally: self.domains_lock.release() - def get_dev_by_uuid(self, klass, dev_uuid, field): - parts = dev_uuid.split('-%s-' % klass, 1) + def get_vm_with_dev_uuid(self, klass, dev_uuid): + self.domains_lock.acquire() try: - if len(parts) > 1: - dom = self.get_vm_by_uuid(parts[0]) - if not dom: - return None - - if field == 'VM': - return dom.get_uuid() - if field == 'uuid': - return dev_uuid - - devid = int(parts[1]) - value = dom.get_device_property(klass, devid, field) - return value + for dom in self.domains.values(): + if dom.has_device(klass, dev_uuid): + return dom + return None + finally: + self.domains_lock.release() + + def get_dev_property_by_uuid(self, klass, dev_uuid, field): + self.domains_lock.acquire() + try: + dom = self.get_vm_with_dev_uuid(klass, dev_uuid) + if not dom: + return None + + value = dom.get_device_property(klass, devid, field) + return value except ValueError, e: pass @@ -588,18 +591,7 @@ class XendDomain: return (self.get_vm_by_uuid(vm_ref) != None) def is_valid_dev(self, klass, dev_uuid): - parts = dev_uuid.split('-%s-' % klass, 1) - try: - if len(parts) > 1: - dom = self.get_vm_by_uuid(parts[0]) - if not dom: - return False - devid = int(parts[1]) - return dom.isDeviceValid(klass, devid) - except ValueError, e: - pass - - return False + return (self.get_vm_with_dev_uuid(klass, dev_uuid) != None) def do_legacy_api_with_uuid(self, fn, vm_uuid, *args): self.domains_lock.acquire() diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index e4902324e1..86c550247f 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1709,54 +1709,73 @@ class XendDomainInfo: return XEN_API_ON_CRASH_BEHAVIOUR.index(self.info['on_crash']) except ValueError, e: return XEN_API_ON_CRASH_BEHAVIOUR.index('destroy') - - def get_device_property(self, devclass, devid, field): - controller = self.getDeviceController(devclass) - - if devclass == 'vif': - if field in ('name', 'MAC', 'type'): - config = controller.getDeviceConfiguration(devid) - if field == 'name': - return config['vifname'] - if field == 'mac': - return config['mac'] - if field == 'type': - return config['type'] - if field == 'device': - return 'eth%s' % devid - if field == 'network': - return None # TODO - if field == 'VM': - return self.get_uuid() - if field == 'MTU': - return 0 # TODO - # TODO: network bandwidth values - return 0.0 - - if devclass == 'vbd': - if field == 'VM': - return self.get_uuid() - if field == 'VDI': - return '' # TODO - if field in ('device', 'mode', 'driver'): - config = controller.getDeviceConfiguration(devid) - if field == 'device': - return config['dev'] # TODO - if field == 'mode': - return config['mode'] - if field == 'driver': - return config['uname'] # TODO - - # TODO network bandwidth values - return 0.0 - - raise XendError("Unrecognised dev class or property") - - - def is_device_valid(self, devclass, devid): - controller = self.getDeviceController(devclass) - return (devid in controller.deviceIDs()) + def get_dev_config_by_uuid(self, dev_class, dev_uuid): + """ Get's a device configuration either from XendConfig or + from the DevController.""" + if self.get_power_state() not in ('Halted',): + dev = self.info['device'].get(dev_uuid) + if dev: + return dev[1].copy() + return None + else: + controller = self.getDeviceController(dev_class) + if not controller: + return None + all_configs = controller.getAllDeviceConfigurations() + if not all_configs: + return None + for _devid, _devcfg in all_configs.items(): + if _devcfg.get('uuid') == dev_uuid: + devcfg = _devcfg.copy() + devcfg['id'] = _devid + return devcfg + + return None + + def get_dev_xenapi_config(self, dev_class, dev_uuid): + config = self.get_dev_config_by_uuid(dev_class, dev_uuid) + if not config: + return {} + + config['VM'] = self.get_uuid() + + if dev_class == 'vif': + if not config.has_key('name'): + config['name'] = config.get('vifname', '') + if not config.has_key('MAC'): + config['MAC'] = config.get('mac', '') + if not config.has_key('type'): + config['type'] = 'paravirtualised' + if not config.has_key('device'): + devid = config.get('id') + if devid != None: + config['device'] = 'eth%d' % devid + else: + config['device'] = '' + + config['network'] = '' # Invalid for Xend + config['MTU'] = 1500 # TODO + config['network_read_kbs'] = 0.0 + config['network_write_kbs'] = 0.0 + config['IO_bandwidth_incoming_kbs'] = 0.0 + config['IO_bandwidth_outgoing_kbs'] = 0.0 + + if dev_class == 'vbd': + config['VDI'] = '' # TODO + config['device'] = config.get('dev', '') + config['driver'] = config.get('uname', '') + config['IO_bandwidth_incoming_kbs'] = 0.0 + config['IO_bandwidth_outgoing_kbs'] = 0.0 + + return config + + def get_dev_property(self, dev_class, dev_uuid, field): + config = self.get_dev_xenapi_config(dev_class, dev_uuid) + try: + return config[field] + except KeyError: + raise XendError('Invalid property for device: %s' % field) def get_vcpus_util(self): # TODO: this returns the total accum cpu time, rather than util @@ -1806,7 +1825,9 @@ class XendDomainInfo: raise XendError("Device creation failed") return dev_uuid - + + def has_device(self, dev_class, dev_uuid): + return (dev_uuid in self.info['%s_refs' % dev_class]) """ def stateChar(name): diff --git a/tools/python/xen/xend/server/DevController.py b/tools/python/xen/xend/server/DevController.py index 16797312d4..1284c8b65d 100644 --- a/tools/python/xen/xend/server/DevController.py +++ b/tools/python/xen/xend/server/DevController.py @@ -256,6 +256,13 @@ class DevController: return {'backend': int(backdomid)} + def getAllDeviceConfigurations(self): + all_configs = {} + for devid in self.deviceIDs(): + config_dict = self.getDeviceConfiguration(devid) + all_configs[devid] = config_dict + return all_configs + ## protected: def getDeviceDetails(self, config): -- 2.30.2